package com.hjx.windowtool.cmd;

import java.awt.EventQueue;
import java.awt.FileDialog;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JTextField;
import javax.swing.UIManager;

import com.hjx.windowtool.win.User32Api;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;

import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.awt.event.ActionEvent;
import javax.swing.JSplitPane;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.JOptionPane;

import java.awt.FlowLayout;
import java.awt.HeadlessException;

import javax.swing.JComboBox;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;

import javax.swing.DefaultComboBoxModel;

public class AutoKeyBordApp {

	private JFrame frame;
	private JTextField textField;
	private int handle;
	private JTextField txt_delay;
	private JTextField txt_keyTimes;
	private JTextField txt_mouseTimes;
	StringListModel model = new StringListModel();
	private JList list;
	
	private boolean isStart=false;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
					AutoKeyBordApp window = new AutoKeyBordApp();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public AutoKeyBordApp() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 663, 484);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel panel = new JPanel();
		FlowLayout flowLayout = (FlowLayout) panel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);
		frame.getContentPane().add(panel, BorderLayout.NORTH);
		
		JLabel lblNewLabel = new JLabel("进程");
		panel.add(lblNewLabel);
		
		textField = new JTextField();
		textField.setEditable(false);
		panel.add(textField);
		textField.setColumns(15);
		
		JButton button = new JButton("选择");
		button.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				WindowsListDialog d = new WindowsListDialog();
				d.open();
				System.out.println(d.getResult());
				String open=d.getResult();
				if(open==null) {
					return;
				}
				String[] split = open.split("-");
				handle = Integer.valueOf(split[0]);
				textField.setText(split[1]);
			}
		});
		panel.add(button);
		
		JButton button_1 = new JButton("启动");
		button_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				keyevent(handle,'f');
			}
			
		});
		panel.add(button_1);
		
		JSplitPane splitPane = new JSplitPane();
		splitPane.setResizeWeight(1.0);
		frame.getContentPane().add(splitPane, BorderLayout.CENTER);
		
		JPanel panel_1 = new JPanel();
		splitPane.setLeftComponent(panel_1);
		panel_1.setLayout(null);
		
		JLabel label = new JLabel("按键");
		label.setBounds(10, 10, 36, 15);
		panel_1.add(label);
		
		JComboBox comboBox = new JComboBox();
		comboBox.setModel(new DefaultComboBoxModel(getKeys()));
		comboBox.setBounds(56, 7, 66, 21);
		comboBox.setSelectedItem("1");
		
		panel_1.add(comboBox);
		
		JButton button_6 = new JButton("插入");
		button_6.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Object selectedItem = comboBox.getSelectedItem();
				System.out.println(selectedItem);
				String s="按键 "+selectedItem+" 执行 "+txt_keyTimes.getText()+"次";
				model.add(s);
			}
		});
		button_6.setBounds(201, 6, 93, 23);
		panel_1.add(button_6);
		
		JLabel label_1 = new JLabel("鼠标");
		label_1.setBounds(10, 47, 36, 15);
		panel_1.add(label_1);
		
		JComboBox cb_mouseKey = new JComboBox();
		cb_mouseKey.setModel(new DefaultComboBoxModel(new String[] {"左键", "右键"}));
		cb_mouseKey.setBounds(56, 44, 66, 21);
		panel_1.add(cb_mouseKey);
		
		JButton button_7 = new JButton("插入");
		button_7.setBounds(201, 43, 93, 23);
		panel_1.add(button_7);
		
		JLabel label_2 = new JLabel("延迟");
		label_2.setBounds(10, 87, 36, 15);
		panel_1.add(label_2);
		
		txt_delay = new JTextField();
		txt_delay.setText("1000");
		txt_delay.setBounds(56, 84, 66, 21);
		panel_1.add(txt_delay);
		txt_delay.setColumns(10);
		
		JButton button_8 = new JButton("插入");
		button_8.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String s="延时 "+txt_delay.getText()+" 毫秒";
				model.add(s);
			}
		});
		button_8.setBounds(201, 83, 93, 23);
		panel_1.add(button_8);
		
		txt_keyTimes = new JTextField();
		txt_keyTimes.setText("1");
		txt_keyTimes.setBounds(132, 7, 36, 21);
		panel_1.add(txt_keyTimes);
		txt_keyTimes.setColumns(10);
		
		JLabel label_3 = new JLabel("次");
		label_3.setBounds(172, 10, 19, 15);
		panel_1.add(label_3);
		
		txt_mouseTimes = new JTextField();
		txt_mouseTimes.setText("1");
		txt_mouseTimes.setColumns(10);
		txt_mouseTimes.setBounds(132, 44, 36, 21);
		panel_1.add(txt_mouseTimes);
		
		JLabel label_4 = new JLabel("次");
		label_4.setBounds(172, 47, 19, 15);
		panel_1.add(label_4);
		
		JPanel panel_2 = new JPanel();
		splitPane.setRightComponent(panel_2);
		panel_2.setLayout(new BorderLayout(0, 0));
		
		JPanel panel_5 = new JPanel();
		panel_2.add(panel_5, BorderLayout.SOUTH);
		
		JButton button_2 = new JButton("启动");
		
		button_2.addActionListener(new ActionListener() {
			private Thread thread;

			public void actionPerformed(ActionEvent e) {
				if(handle==0) {
					JOptionPane.showMessageDialog(frame, "先选择个窗口");
					return;
				}
				if (!isStart) {
					isStart=!isStart;
					thread = new Thread(new Runnable() {

						@Override
						public void run() {
							while (isStart) {
								for (String string : model.getListSource()) {
									String[] split = string.split(" ");
									if (string.startsWith("按键")) {
										int keyCode = getKeyCode(split[1]);
										if (keyCode == 0) {
											continue;
										}
										keyevent(handle, keyCode);
									}
									if (string.startsWith("延时")) {
										try {
											Thread.sleep(Integer.valueOf(split[1]));
										} catch (InterruptedException e) {
											break;
										}
									}
								}
							}
						}

					});
					thread.start();
					button_2.setText("停止");
				}else {
					isStart=!isStart;
					thread.interrupt();
					button_2.setText("启动");
				}
			}
		});
		panel_5.add(button_2);
		
		JButton button_3 = new JButton("删除");
		button_3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedIndex = list.getSelectedIndex();
				System.out.println(selectedIndex);
				if(selectedIndex<0) {
					return;
				}
				model.remove(selectedIndex);
			}
		});
		panel_5.add(button_3);
		
		JButton button_4 = new JButton("保存");
		button_4.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
//					String saveFile = JOptionPane.showInputDialog("请输入保存文件名");
					File file = new File("script\\"+1+".ini");
					if(!file.exists()) {
						file.getParentFile().mkdirs();
						file.createNewFile();
					}
					Files.write(file.toPath(), model.getListSource());
					JOptionPane.showConfirmDialog(frame, "保存成功");
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		});
		panel_5.add(button_4);
		
		JButton button_5 = new JButton("读取");
		button_5.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
//					String saveFile = JOptionPane.showInputDialog("请输入保存文件名");
					File file = new File("script\\"+1+".ini");
					if(!file.exists()) {
						JOptionPane.showConfirmDialog(frame, "读取失败");
						return;
					}
					List<String> lines = Files.readAllLines(file.toPath());
					if(lines!=null&&!lines.isEmpty()) {
						model.setListSource(lines);
					}
					JOptionPane.showConfirmDialog(frame, "读取成功");
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		});
		panel_5.add(button_5);
		
		JScrollPane scrollPane = new JScrollPane();
		panel_2.add(scrollPane, BorderLayout.CENTER);
		
		list = new JList(model);
		scrollPane.setViewportView(list);
	}
	/**
	 * @param hWnd
	 * @return
	 */
	public List<HWND> findChildWindow(HWND hWnd) {
		HWND child=null;
		List<HWND> childs=new ArrayList<>();
		while((child=User32Api.api.FindWindowEx(hWnd, child, null, null))!=null) {
			System.out.println(child);
			childs.add(child);
			List<HWND> findChildWindow = findChildWindow(child);
			childs.addAll(findChildWindow);
		}
		return childs;
	}
	
	public String[] getKeys() {
		List<String> list=new ArrayList<>();
		Field[] declaredFields = KeyEvent.class.getDeclaredFields();
		for (Field field : declaredFields) {
			String name = field.getName();
			if(name.startsWith("VK_")) {
				list.add(name.substring(3));
			}
		}
		return list.toArray(new String[list.size()]);
	}
	
	public int getKeyCode(String keyName) {
		try {
			Field field = KeyEvent.class.getDeclaredField("VK_"+keyName);
			if(field==null) {
				return 0;
			}
			return (int) field.get(KeyEvent.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}
	
	/**
	 * 
	 */
	public void keyevent(int handle,int keyCode) {
		HWND hWnd = new HWND(Pointer.createConstant(handle));
		List<HWND> childs = findChildWindow(hWnd);
		boolean sendMessage = User32Api.api.PostMessage(handle, User32.WM_KEYDOWN, keyCode, 0);
		System.out.println(sendMessage);
		sendMessage =User32Api.api.PostMessage(handle, User32.WM_KEYUP, keyCode, 0);
		System.out.println(sendMessage);
		for (HWND hwnd2 : childs) {
			int nativeValue = (int) Pointer.nativeValue(hwnd2.getPointer());
			System.out.println(Integer.toHexString(nativeValue));
			sendMessage = User32Api.api.PostMessage(nativeValue, User32.WM_KEYDOWN, keyCode, 0);
			System.out.println(sendMessage);
			sendMessage =User32Api.api.PostMessage(nativeValue, User32.WM_KEYUP, keyCode, 0);
			System.out.println(sendMessage);
		}
	}
}
